#include "pos_param.h"
#include "XRCORE.h"
#include <string.h>
#include "gd32e230c_bsp.h"
#include "TM1638.h"
#include "pos_timer.h"
#include "display.h"

//#define DoReadN EEPROM_read_n
//#define DoWriteN EEPROM_write_n
//#define DoWriteN1(addr,pdata,len) write_flash1(addr,(uint32_t *)pdata,len)

volatile TPosParam PosParam;
#ifdef DUAL_MODE   
volatile tDualRatMode DualRatMode;
#endif
static uint8_t BlockBuf[128];    

uint16_t ReadBlock (uint16_t Address)
{
    read_flash (Address, BlockBuf, 128);

    if (BlockBuf[126] != BytesXor(BlockBuf, 0, 128 - 2)){
        return 1;
    }
    if (BlockBuf[127] != BytesAddReverse(BlockBuf, 0, 128 - 2)) {   
        return 1;
    }

    return 0;
}

void SignBlock()
{
    BlockBuf[126] = BytesXor ( BlockBuf, 0, 128 - 2 );
    BlockBuf[127] = BytesAddReverse ( BlockBuf, 0, 128 - 2); //48??????0x48
}

// { ???? 0x00~0x49 }
void ReadParam()
{
    if (ReadBlock(0xFC00) != 0)      // 0x0800F800 ??   1?1024???
    {   return; }

    PosParam.M1Purse.Sector   = BlockBuf[0];          // M1?????
    PosParam.M1Purse.DataType = BlockBuf[1];          // M1???????? 0 ?? 1 ???
    PosParam.M1Purse.KeyType  = BlockBuf[2];          // M1????????: 1 ?? 7 ??
    memmove((void *)PosParam.M1Purse.Key, &BlockBuf[3], 6);    // M1??????

    PosParam.M1PurseSub.Sector = BlockBuf[9];         // M1?????
    PosParam.M1PurseSub.DataType = BlockBuf[10];      // M1????????
    PosParam.M1PurseSub.KeyType = BlockBuf[11];       // M1????????
    memmove((void *)PosParam.M1PurseSub.Key, &BlockBuf[12], 6); // M1??????

    PosParam.CPUPurse.Sector = BlockBuf[18];          // CPU????
    PosParam.CPUPurse.DataType = BlockBuf[19];        // CPU?????
    PosParam.CPUPurse.KeyType = BlockBuf[20];         // CPU?????
    memmove((void *)PosParam.CPUPurse.Key, &BlockBuf[21], 6);  // CPU???

    memmove((void *)&PosParam.AuthCode, &BlockBuf[27], 2);     // ???
    memmove((void *)PosParam.PosIP, &BlockBuf[29], 2);         // ????
    PosParam.CPU_B = BlockBuf[31];        // ?CPU B??
    PosParam.Prev_UID = BlockBuf[32];     // ?UID?

    //?? WorkParam , ?[40] ??
    memmove((void *)&PosParam.MeasureMode,          &BlockBuf[40], 1);  // ???? ??/??
    memmove((void *)&PosParam.OutPulse,             &BlockBuf[41], 2);  // 1?????
    memmove((void *)&PosParam.OutFee,               &BlockBuf[43], 2);  // 1?????

    memmove((void *)&PosParam.PosMult16,            &BlockBuf[45], 1);
    memmove((void *)&PosParam.StopSec,              &BlockBuf[46], 2);  
    memmove((void *)&PosParam.BackLight,            &BlockBuf[48], 1);
    memmove((void *)&PosParam.ChargeDelay,          &BlockBuf[49], 1);  // ??????
    memmove((void *)&PosParam.EnableUserCard,       &BlockBuf[50], 1);

    memmove((void *)&PosParam.DayLimit,             &BlockBuf[51], 2);  // ???????
    memmove((void *)&PosParam.DayLimitFlag,         &BlockBuf[53], 1);  // ?????
    
    memmove((void *)&PosParam.FreeUseFee,           &BlockBuf[54], 1); 
    memmove((void *)&PosParam.FreeUsePluse,         &BlockBuf[55], 1); 
    memmove((void *)&PosParam.FreeUseMode,          &BlockBuf[56], 1);
    memmove((void *)&PosParam.FreeUseTotal,         &BlockBuf[57], 2);
	memmove((void *)&PosParam.FreeRemWarn,          &BlockBuf[59], 2);
    memmove((void *)&PosParam.FreeUseMonFlag,       &BlockBuf[61], 1);

    memmove((void *)&PosParam.SpecDeduFee,          &BlockBuf[62], 1);
    memmove((void *)&PosParam.SpecDeduPulse,        &BlockBuf[63], 1);
    memmove((void *)&PosParam.SpecDeduMode,         &BlockBuf[64], 1); //StartConsumption?????????
    memmove((void *)&PosParam.SpecDeduInCrad,       &BlockBuf[65], 1); //24???????????

    memmove((void *)&PosParam.RationModeFee,        &BlockBuf[66], 1); // ??????
    memmove((void *)&PosParam.RationModeTime,       &BlockBuf[67], 2);
    memmove((void *)&PosParam.RationMode,           &BlockBuf[69], 1); // ??????
    memmove((void *)&PosParam.RationInCrad,         &BlockBuf[70], 1);

    memmove((void *)&PosParam.RetenMoney,           &BlockBuf[71], 2); //????
    memmove((void *)&PosParam.RetenMoneyFlag,       &BlockBuf[73], 1); //??????
    memmove((void *)&PosParam.MaxBalance,           &BlockBuf[74], 2);
    memmove((void *)&PosParam.MaxBalance_Flag,      &BlockBuf[76], 1);    
    
    memmove((void *)&PosParam.PulsesPerLiter,       &BlockBuf[77], 2);
    memmove((void *)&PosParam.LiterDisplay,         &BlockBuf[79], 1);
#ifdef DUAL_MODE
    memmove((void *)&PosParam.Dual_RationMode,         &BlockBuf[80], 1);  
    memmove((void *)&PosParam.Dual_1RationModeFee,     &BlockBuf[81], 2);  
    memmove((void *)&PosParam.Dual_1RationModeTime,    &BlockBuf[83], 2);  
    memmove((void *)&PosParam.Dual_2RationModeFee,     &BlockBuf[85], 2);  
    memmove((void *)&PosParam.Dual_2RationModeTime,    &BlockBuf[87], 2);  
    
    memmove((void *)&PosParam.DualMode,                &BlockBuf[89], 1);  
    memmove((void *)&PosParam.DualControlMode_1,       &BlockBuf[90], 1); 
    memmove((void *)&PosParam.DualControlMode_2,       &BlockBuf[91], 1); 
    memmove((void *)&PosParam.Out1Pulse,               &BlockBuf[92], 2);  
    memmove((void *)&PosParam.Out1Fee,                 &BlockBuf[94], 2);  
    memmove((void *)&PosParam.Out2Pulse,               &BlockBuf[96], 2);  
    memmove((void *)&PosParam.Out2Fee,                 &BlockBuf[98], 2);  

    memmove((void *)&PosParam.PulseOutMode,            &BlockBuf[100], 1);  
    memmove((void *)&PosParam.PosMult16_2,             &BlockBuf[101], 1);  
    memmove((void *)&PosParam.DualControlMode,         &BlockBuf[102], 1); 

    memmove((void *)&DualRatMode.Incr,   &BlockBuf[105], 1);             //???  2023-4-4
#endif
    memmove((void *)&PosParam.NFC_Gain,  &BlockBuf[103], 1);
#ifndef SEGLCD
    memmove((void *)&PosParam.LedLumin,  &BlockBuf[104], 1);
#endif  
}

void SaveParam()
{
    memset(BlockBuf, 0x00, 128);        // BlockBuf ??

    BlockBuf[0]  = PosParam.M1Purse.Sector;
    BlockBuf[1]  = PosParam.M1Purse.DataType;
    BlockBuf[2]  = PosParam.M1Purse.KeyType;
    memmove(&BlockBuf[3], (void *)PosParam.M1Purse.Key, 6);

    BlockBuf[9]  = PosParam.M1PurseSub.Sector;
    BlockBuf[10] = PosParam.M1PurseSub.DataType;
    BlockBuf[11] = PosParam.M1PurseSub.KeyType;
    memmove(&BlockBuf[12], (void *)PosParam.M1PurseSub.Key, 6);

    BlockBuf[18] = PosParam.CPUPurse.Sector;
    BlockBuf[19] = PosParam.CPUPurse.DataType;
    BlockBuf[20] = PosParam.CPUPurse.KeyType;
    memmove(&BlockBuf[21], (void *)PosParam.CPUPurse.Key, 6);

    memmove(&BlockBuf[27], (void *)&PosParam.AuthCode, 2);
    memmove(&BlockBuf[29], (void *)PosParam.PosIP, 2);
    BlockBuf[31] = PosParam.CPU_B;
    BlockBuf[32] = PosParam.Prev_UID;
    //memset(&BlockBuf[33], 0x00, 7);          

    //WorkParam ????  ?[40] ??
    memmove(&BlockBuf[40], (void *)&PosParam.MeasureMode,      1);
    memmove(&BlockBuf[41], (void *)&PosParam.OutPulse,         2);
    memmove(&BlockBuf[43], (void *)&PosParam.OutFee,           2);

    memmove(&BlockBuf[45], (void *)&PosParam.PosMult16,        1);
    memmove(&BlockBuf[46], (void *)&PosParam.StopSec,          2);
    memmove(&BlockBuf[48], (void *)&PosParam.BackLight,        1);  
    memmove(&BlockBuf[49], (void *)&PosParam.ChargeDelay,      1);
    memmove(&BlockBuf[50], (void *)&PosParam.EnableUserCard,   1);//??????

    memmove(&BlockBuf[51], (void *)&PosParam.DayLimit,         2);
    memmove(&BlockBuf[53], (void *)&PosParam.DayLimitFlag,     1);//?????

    memmove(&BlockBuf[54], (void *)&PosParam.FreeUseFee,       1);
    memmove(&BlockBuf[55], (void *)&PosParam.FreeUsePluse,     1);
    memmove(&BlockBuf[56], (void *)&PosParam.FreeUseMode,      1);//??????
    memmove(&BlockBuf[57], (void *)&PosParam.FreeUseTotal,     2);
	memmove(&BlockBuf[59], (void *)&PosParam.FreeRemWarn,      2);//????????
    memmove(&BlockBuf[61], (void *)&PosParam.FreeUseMonFlag,   1);

    memmove(&BlockBuf[62], (void *)&PosParam.SpecDeduFee,      1);
    memmove(&BlockBuf[63], (void *)&PosParam.SpecDeduPulse,    1);
    memmove(&BlockBuf[64], (void *)&PosParam.SpecDeduMode,     1);//?????????
    memmove(&BlockBuf[65], (void *)&PosParam.SpecDeduInCrad,   1);//24???????????

    memmove(&BlockBuf[66], (void *)&PosParam.RationModeFee,    1);
    memmove(&BlockBuf[67], (void *)&PosParam.RationModeTime,   2);
    memmove(&BlockBuf[69], (void *)&PosParam.RationMode,       1);
    memmove(&BlockBuf[70], (void *)&PosParam.RationInCrad,     1);

    memmove(&BlockBuf[71], (void *)&PosParam.RetenMoney,       2);//??????
    memmove(&BlockBuf[73], (void *)&PosParam.RetenMoneyFlag,   1);//????
    memmove(&BlockBuf[74], (void *)&PosParam.MaxBalance,       2);
    memmove(&BlockBuf[76], (void *)&PosParam.MaxBalance_Flag,  1);

    memmove(&BlockBuf[77], (void *)&PosParam.PulsesPerLiter,   2);//??????
    memmove(&BlockBuf[79], (void *)&PosParam.LiterDisplay,     1);

#ifdef DUAL_MODE
    memmove(&BlockBuf[80], (void *)&PosParam.Dual_RationMode,       1);  
    memmove(&BlockBuf[81], (void *)&PosParam.Dual_1RationModeFee,   2);  
    memmove(&BlockBuf[83], (void *)&PosParam.Dual_1RationModeTime,  2);  
    memmove(&BlockBuf[85], (void *)&PosParam.Dual_2RationModeFee,   2);  
    memmove(&BlockBuf[87], (void *)&PosParam.Dual_2RationModeTime,  2);  
    
    memmove(&BlockBuf[89], (void *)&PosParam.DualMode,              1);  
    memmove(&BlockBuf[90], (void *)&PosParam.DualControlMode_1,     1); 
    memmove(&BlockBuf[91], (void *)&PosParam.DualControlMode_2,     1); 
    memmove(&BlockBuf[92], (void *)&PosParam.Out1Pulse,             2);  
    memmove(&BlockBuf[94], (void *)&PosParam.Out1Fee,               2);  
    memmove(&BlockBuf[96], (void *)&PosParam.Out2Pulse,             2);  
    memmove(&BlockBuf[98], (void *)&PosParam.Out2Fee,               2);  

    memmove(&BlockBuf[100], (void *)&PosParam.PulseOutMode,          1); 
    memmove(&BlockBuf[101], (void *)&PosParam.PosMult16_2,           1); 
    memmove(&BlockBuf[102], (void *)&PosParam.DualControlMode,       1); 

    memmove(&BlockBuf[102], (void *)&PosParam.DualControlMode,       1); 

    memmove(&BlockBuf[105], (void *)&DualRatMode.Incr,      1);    //???  2023-4-4
#endif
    memmove(&BlockBuf[103], (void *)&PosParam.NFC_Gain,     1);
#ifndef SEGLCD
    memmove(&BlockBuf[104], (void *)&PosParam.LedLumin,     1);
#endif  
    SignBlock();
    write_flash(0xFC00, (uint32_t *)BlockBuf, 128);     // 0x0800FC00 ??   1?1024???
}

void InitPosParam()
{
    PosParam.SaveParam = SaveParam;
    //PosParam.SaveWorkParam = SaveWorkParam;

    ReadParam();
    // ReadWorkParam();
    ReadAmountFun();
}

void SetFactory()
{
    static uint8_t BlockBuf1[16];
    const uint8_t DefaultKey[6] = {0x05, 0x51, 0x80, 0x01, 0x05, 0x51};

    PosParam.M1Purse.Sector = 8;
    PosParam.M1Purse.DataType = 0;
    PosParam.M1Purse.KeyType = 7;
    memmove((void *)PosParam.M1Purse.Key, DefaultKey, 6);

    PosParam.M1PurseSub.Sector = 9;
    PosParam.M1PurseSub.DataType = 0;
    PosParam.M1PurseSub.KeyType = 7;
    memmove((void *)PosParam.M1PurseSub.Key, DefaultKey, 6);

    // todo: ??CPU???????1501????
    PosParam.AuthCode = 0x6004;
    PosParam.PosIP[0] = 0xFF;
    PosParam.PosIP[1] = 0xFF;

    PosParam.RationMode = 0x00;
    PosParam.MeasureMode = 0x10; 
    if(PosParam.MeasureMode == 0x20 || PosParam.MeasureMode == 0x30){
        PosParam.PosMult16 = 16;
    }else{
        PosParam.PosMult16 = 1;
    }
    PosParam.OutPulse = 0x01;
    PosParam.OutFee = 0x01;
    PosParam.BackLight      = 1; // ??
    PosParam.FreeUseMode    = 0; // ????
    PosParam.DayLimitFlag   = 0; // ???
    PosParam.EnableUserCard = 0; //??CPU??M1?????
    PosParam.SpecDeduInCrad = 0; //24???????
    PosParam.SpecDeduMode   = 0; // ????????
    PosParam.ChargeDelay    = 0; // ??????
    PosParam.RetenMoneyFlag = 0x00;
    PosParam.CPU_B          = 0;
    PosParam.Prev_UID       = 0;
#ifdef DUAL_MODE
    PosParam.DualMode         = 0;
    PosParam.Dual_RationMode  = 0;
    DualRatMode.Incr          = 0;
    PosParam.PulseOutMode     = 0; // ??????
#endif    
    PosParam.NFC_Gain = 0x48;   //??????
#ifndef SEGLCD
    PosParam.LedLumin = 0x88;
    TM1638_WriteCmd(0x88 | PosParam.LedLumin);     //?? (0x88-0x8f)8?????
#endif
    Disp_Init();
    SaveParam();
    ReadParam();
}

//??????
void SaveAmountFun()   // 0x0800F400 ??   1?128???
{
    static uint8_t BlockBuf1[16];

    //memset(BlockBuf1, 0x00, 16);
    memmove(&BlockBuf1, (uint32_t *)&PosParam.Amtall, 4);
    memmove(&BlockBuf1[4], (void *)&G_Standby,  1);
    BlockBuf[14] = BytesXor(BlockBuf1, 0, 0x0E);
    BlockBuf[15] = BytesAddReverse(BlockBuf1, 0, 0x0E);
    write_flash(0xF800, (uint32_t *)BlockBuf1, 16);
}

void ReadAmountFun()
{
    static uint8_t BlockBuf1[16];

    read_flash(0xF800, BlockBuf1, 16);
    memmove((uint32_t *)&PosParam.Amtall, &BlockBuf1, 4);    //??????

    if (PosParam.Amtall == 0xFFFFFFFF){
        PosParam.Amtall = 0;
    }
}
void ReadStandbyFlag()
{
    static uint8_t BlockBuf1[8];

    read_flash(0xF800, BlockBuf1, 8);
    memmove((void *)&G_Standby, &BlockBuf1[4], 1); 
}
